<!--
// Plotting ln(x) with its approximations using Taylor series.
// The plotting is done with Plotly.js.
//
// Eli Bendersky [https://eli.thegreenplace.net]
// This code is in the public domain.
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>ln with approximations</title>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML'></script>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>

<body>
    <div id="plot"></div>
    <script>
        function series(n, x) {
            let sum = 0;
            let sign = 1;
            for (let i = 1; i < n; i++) {
                sum += sign * Math.pow(x - 1, i) / i;
                sign *= -1;
            }
            return sum;
        }

        let N = 6;
        let xValues = [];
        let ys = [];

        // Create an array of N empty arrays in ys
        // ys[0] is the ln function
        // ys[1] to ys[N-1] are the approximations
        for (let i = 0; i < N; i++) {
            ys.push([]);
        }

        // Populate data for xs and ys
        for (let x = 0.1; x <= 9; x += 0.01) {
            xValues.push(x);
            ys[0].push(Math.log(x));

            for (let n = 1; n < N; n++) {
                let v = series(n, x);
                if (v > -3 && v < 3) {
                    // Clip the approximation to a small range for plotting;
                    // we don't care about these polyinomials' behavior outside
                    // this range (they "blow up" quickly).
                    ys[n].push(series(n, x));
                }
            }
        }

        // Define the traces for the functions. First go the approximations,
        // then the ln function (so it gets drawn on top).
        let traces = [];
        for (let n = 1; n < N; n++) {
            traces.push({
                x: xValues,
                y: ys[n],
                type: 'scatter',
                mode: 'lines',
                line: { color: `lightblue` },
            });
        }

        traces.push({
            x: xValues,
            y: ys[0],
            type: 'scatter',
            mode: 'lines',
            line: { color: `blue` },
            name: `ln(x)`
        })

        // Define annotations for the plot
        let annotations = [
            { x: 0.2, y: 0.2, showarrow: false, text: 'k=1' },
            { x: 3.8, y: 2.4, showarrow: false, text: 'k=2' },
            { x: 3.8, y: -0.8, showarrow: false, text: 'k=3' },
            { x: 2.7, y: 2.5, showarrow: false, text: 'k=4' },
            { x: 2.7, y: -0.7, showarrow: false, text: 'k=5' },
        ];

        // Define the layout for the plot
        let layout = {
            title: 'ln with approximations',
            xaxis: {
                range: [0, 4],
                title: 'x'
            },
            yaxis: {
                title: 'y'
            },
            showlegend: false,
            width: 700,
            annotations: annotations
        };

        // Plot the data
        Plotly.newPlot('plot', traces, layout);
    </script>
</body>

</html>